from sqlalchemy.orm import Session
from typing import Optional, List, Dict, Any
from datetime import datetime

from src.database.manager import DBManager
from src.database.models import GeneratedVideo
from src.utils.logger import log_info, log_error

class GeneratedVideoDAO:
    """Data Access Object for GeneratedVideo model."""
    
    def __init__(self, session: Session = DBManager().get_session()):
        self.session = session
    
    def create(self, config_id: int, file_path: str, filename: str, output_folder: str,
               source_videos: List = None, audio_path: str = None,
               combination_number: int = None, file_size: int = None,
               duration: float = None, status: str = "processing") -> GeneratedVideo:
        """Create a new generated video record."""
        try:
            video = GeneratedVideo(
                config_id=config_id,
                file_path=file_path,
                filename=filename,
                output_folder=output_folder,
                source_videos=source_videos or [],
                audio_path=audio_path,
                combination_number=combination_number,
                file_size=file_size,
                duration=duration,
                status=status,
                created_at=datetime.now()
            )
            
            self.session.add(video)
            self.session.commit()
            log_info(f"Created generated video record with ID: {video.id}")
            return video
        except Exception as e:
            self.session.rollback()
            log_error(f"Error creating generated video record: {e}")
            raise
            
    def get_by_id(self, video_id: int) -> Optional[GeneratedVideo]:
        """Get generated video by ID."""
        return self.session.query(GeneratedVideo).filter(GeneratedVideo.id == video_id).first()
    
    def update_status(self, video_id: int, status: str, error_message: str = None) -> bool:
        """Update the status of a generated video."""
        video = self.get_by_id(video_id)
        if not video:
            return False
            
        video.status = status
        if error_message:
            video.error_message = error_message
            
        self.session.commit()
        return True
        
    def get_by_config_id(self, config_id: int) -> List[GeneratedVideo]:
        """Get all generated videos for a specific configuration."""
        return self.session.query(GeneratedVideo)\
            .filter(GeneratedVideo.config_id == config_id)\
            .order_by(GeneratedVideo.created_at.desc())\
            .all()
    
    def get_paginated(self, page: int = 1, page_size: int = 10) -> Dict[str, Any]:
        """Get paginated list of generated videos."""
        offset = (page - 1) * page_size
        
        # Get total count
        total_count = self.session.query(GeneratedVideo).count()
        
        # Get page data
        videos = self.session.query(GeneratedVideo)\
            .order_by(GeneratedVideo.created_at.desc())\
            .limit(page_size).offset(offset).all()
        
        # Calculate total pages
        total_pages = (total_count + page_size - 1) // page_size
        
        return {
            "success": True,
            "data": {
                "records": [self._to_dict(video) for video in videos],
                "pagination": {
                    "page": page,
                    "page_size": page_size,
                    "total_count": total_count,
                    "total_pages": total_pages
                }
            }
        }
    
    def _to_dict(self, video: GeneratedVideo) -> Dict[str, Any]:
        """Convert GeneratedVideo object to dictionary."""
        return {
            "id": video.id,
            "config_id": video.config_id,
            "file_path": video.file_path,
            "filename": video.filename,
            "output_folder": video.output_folder,
            "source_videos": video.source_videos,
            "audio_path": video.audio_path,
            "combination_number": video.combination_number,
            "file_size": video.file_size,
            "duration": video.duration,
            "status": video.status,
            "error_message": video.error_message,
            "created_at": video.created_at.strftime("%Y-%m-%d %H:%M:%S") if video.created_at else None
        }